package settings

import (
	"fmt"
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
)

// Conf 全局变量，用来保存程序的所有配置信息
var Conf = new(AppConfig)

type AppConfig struct {
	Name         string `mapstructure:"name"`
	Mode         string `mapstructure:"mode"`
	Version      string `mapstructure:"version"`
	Port         int    `mapstructure:"port"`
	*LogConfig   `mapstructure:"log"`
	*MySQLConfig `mapstructure:"mysql"`
	*RedisConfig `mapstructure:"redis"`
}

type LogConfig struct {
	Level      string `mapstructure:"level"`
	Filename   string `mapstructure:"filename"`
	MaxSize    int    `mapstructure:"max_size"`
	MaxAge     int    `mapstructure:"max_age"`
	MaxBackups int    `mapstructure:"max_backups"`
}

type MySQLConfig struct {
	Host         string `mapstructure:"host"`
	User         string `mapstructure:"user"`
	Password     string `mapstructure:"password"`
	DbName       string `mapstructure:"dbName"`
	Port         int    `mapstructure:"port"`
	MaxOpenConns int    `mapstructure:"max_open_conns"`
	MaxIdleConns int    `mapstructure:"max_idle_conns"`
}

type RedisConfig struct {
	Host     string `mapstructure:"host"`
	Password string `mapstructure:"password"`
	Port     int    `mapstructure:"port"`
	DB       int    `mapstructure:"DB"`
	PoolSize int    `mapstructure:"poolSize"`
}

func Init(filePath string) (err error) {
	//viper.SetConfigFile("./10_web_app2/settings/config.yaml")
	//viper.SetConfigName("config")                //设置配置文件名称（不需要带后缀）
	//viper.SetConfigType("yaml")                  //指定配置文件类型（专门用于从远程获取配置信息时指定配置文件类型的）
	//viper.AddConfigPath("./10_web_app2/settings") // 指定查找配置文件的路径（这里使用相对路径）

	//方式1：直接指定配置文件路径（相对路径或者绝对路径）
	//相对路径：相对执行的可执行文件的相对路径
	//viper.SetConfigFile("./10_web_app2/settings/config.yaml")
	//绝对路径：系统中实际的文件路径
	//viper.SetConfigFile("E:/代码文件/GO/src/GoWeb进阶/10_web_app2/settings/config.yaml")

	//方式2：指定配置文件名和配置文件的位置，viper 自行查找可用的配置文件
	//配置文件名不需要带后缀
	//配置文件位置可配置多个
	//viper.SetConfigName("config")                       // 配置文件名称(无扩展名)
	//viper.AddConfigPath("/etc/appname/")                // 指定查找配置文件的路径
	//viper.AddConfigPath("$HOME/.appname")               // 多次调用以添加多个搜索路径
	//viper.AddConfigPath(".")                            // 还可以在工作目录中查找配置
	//viper.AddConfigPath("./10_web_app2/settings")              // 指定查找配置文件的路径（这里使用相对路径）

	//基本上是配合远程配置中心使用的，告诉 viper 当前的数据使用什么格式去解析
	//viper.SetConfigType("yaml") //指定配置文件类型（专门用于从远程获取配置信息时指定配置文件类型的）

	viper.SetConfigFile(filePath)

	err = viper.ReadInConfig() //读取配置信息
	if err != nil {
		//读取配置信息失败
		fmt.Printf("viper.ReadInConfig() failed, err: %v\n", err)
		return
	}

	//把读取到的配置信息反序列化到 Conf 变量中
	if err = viper.Unmarshal(Conf); err != nil {
		fmt.Printf("viper.Unmarshal failed, err:%v\n", err)
	}

	viper.WatchConfig()
	viper.OnConfigChange(func(in fsnotify.Event) {
		fmt.Println("配置文件修改了。。。")
		if err = viper.Unmarshal(Conf); err != nil {
			fmt.Printf("viper.Unmarshal failed, err:%v\n", err)
		}
	})
	return
}
